// 超级万年历综合版（支持公历<->农历、节气、节日、月历、日期计算）
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <locale.h>
#include <math.h>
#include <wchar.h>

#include <stdbool.h>

#ifdef _WIN32
#include <windows.h>
#include <fcntl.h>
#include <io.h>
#endif

#define BASE_YEAR 1900
#define MAX_YEAR 2100
#define MIN_LUNAR_YEAR 1840

//24节气系数
const double solarTermInfo[] = {
    6.11, 20.84, 4.6295, 19.4599, 6.3826, 21.4155,
    5.59, 20.888, 6.318, 21.86, 6.5, 22.2,
    7.928, 23.65, 8.35, 23.95, 8.44, 23.822,
    9.098, 24.218, 8.218, 23.08, 7.9, 22.6
};

const wchar_t *solarTerms[] = {
    L"小寒", L"大寒", L"立春", L"雨水", L"惊蛰", L"春分",
    L"清明", L"谷雨", L"立夏", L"小满", L"芒种", L"夏至",
    L"小暑", L"大暑", L"立秋", L"处暑", L"白露", L"秋分",
    L"寒露", L"霜降", L"立冬", L"小雪", L"大雪", L"冬至"
};


// 农历数据（1900-2100年，201项）
const unsigned int LUNAR_INFO[] = {
    0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,
    0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,
    0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,
    0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,
    0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,
    0x06ca0,0x0b550,0x15355,0x04da0,0x0a5d0,0x14573,0x052d0,0x0a9a8,0x0e950,0x06aa0,
    0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,
    0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b5a0,0x195a6,
    0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,
    0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x05ac0,0x0ab60,0x096d5,0x092e0,
    0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,
    0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,
    0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,
    0x05aa0,0x076a3,0x096d0,0x04bd7,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,
    0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,
    0x14b63,0x09370  // 2100年数据
};


const wchar_t *solarFestivals[][2] = {
    {L"01-01", L"元旦"}, {L"02-14", L"情人节"}, {L"03-08", L"妇女节"},
    {L"03-12", L"植树节"}, {L"04-01", L"愚人节"}, {L"05-01", L"劳动节"},
    {L"06-01", L"儿童节"}, {L"09-10", L"教师节"}, {L"10-01", L"国庆节"},
    {L"12-25", L"圣诞节"}
};

const wchar_t *lunarFestivals[] = {
    L"正月初一 春节", L"正月十五 元宵节", L"五月初五 端午节",
    L"七月初七 七夕节", L"八月十五 中秋节", L"九月初九 重阳节"
};




// 设置区域，初始化
void initLocale() {
    setlocale(LC_ALL, "");
#ifdef _WIN32
    SetConsoleOutputCP(CP_UTF8);
    SetConsoleCP(CP_UTF8);
    _setmode(_fileno(stdout), _O_U8TEXT);
    _setmode(_fileno(stdin), _O_U8TEXT);

#endif
}



// —— 日期/农历转换辅助函数 ——
// 取二进制位
int getBit(unsigned int n, int p) { return (n >> p) & 1; }
// 某年闰月(月号，0 表示无闰月)
int getLeapMonth(int y) { return LUNAR_INFO[y-BASE_YEAR] & 0xf; }
// 某年闰月天数
int getLeapDays(int y) { return getLeapMonth(y) ? (getBit(LUNAR_INFO[y-BASE_YEAR], 16) ? 30 : 29) : 0; }
// 某年某月天数（1–12 月）
int getMonthDays(int y,int m) { return (getBit(LUNAR_INFO[y-BASE_YEAR], 16-m) ? 30 : 29); }
// 某年总天数
int getYearDays(int y) { int sum=348; for(int i=0x8000;i>0x8;i>>=1) sum += (LUNAR_INFO[y-BASE_YEAR] & i)?1:0; return sum+getLeapDays(y); }


// 精确计算节气日（基于天文算法，例如 Jean Meeus 《天文算法》）
int computeSolarTermDay(int year, int idx) {
    // 使用简化天文算法计算节气（以UTC中午为基准）
    double y = (double)(year - 2000) / 100.0;
    double theta = idx * 15.0; // 节气黄经角度：0~345，每次加15°
    double JDE0 = 2451623.80984 + 365242.37404 * y + 0.05169 * y * y - 0.00411 * y * y * y - 0.00057 * y * y * y * y;

    // 粗略线性校正，改进空间大
    double delta = theta / 360.0 * 365.2422; // 从春分开始的偏移（近似）
    double JD = JDE0 + delta;

    // 将JD转换为日期
    int Z = (int)(JD + 0.5);
    double F = (JD + 0.5) - Z;
    int A = (int)((Z - 1867216.25) / 36524.25);
    A = Z >= 2299161 ? Z + 1 + A - A / 4 : Z;
    int B = A + 1524;
    int C = (int)((B - 122.1) / 365.25);
    int D = (int)(365.25 * C);
    int E = (int)((B - D) / 30.6001);
    int day = B - D - (int)(30.6001 * E) + F;

    return day;
}

// 近似旧算法，保留备份
int getSolarTermDayApprox(int y, int idx) {
    return (int)(solarTermInfo[idx] + (y - 1900) * 0.2422 - (int)((y - 1900) / 4));
}

// 新接口：节气日调用精确算法
int getSolarTermDay(int y, int idx) {
    return computeSolarTermDay(y, idx);
}


// 农历<=>>公历转换辅助

// 判断闰年
bool isGregorianLeap(int y) {
    return (y%4==0 && y%100!=0) || (y%400==0);
}

// 某年某月格里高利历天数
int getGregorianMonthDays(int y, int m) {
    static const int md[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    if (m == 2 && isGregorianLeap(y)) return 29;
    return md[m];
}

// 公历日期转与基准天数偏移
// 计算从 1900-01-31 开始到 y-m-d 一共过去多少天
// 1900-01-31 对应 offset=0，1900-02-01 对应 offset=1，依此类推
int daysFromBase(int y, int m, int d) {
    // 1) 累加 1900 到前一年完整的天数
    int days = 0;
    for (int year = 1900; year < y; year++) {
        days += isGregorianLeap(year) ? 366 : 365;
    }

    // 2) 累加当年到前一个月的天数
    static const int mdays[] = {31,28,31,30,31,30,31,31,30,31,30,31};
    for (int month = 1; month < m; month++) {
        days += mdays[month - 1];
        if (month == 2 && isGregorianLeap(y)) days++;
    }

    // 3) 累加当月的天数，但是减去基准日 31 → offset 从 0 开始
    days += d - 31;

    return days;
}

// 公历->农历
void solarToLunarDate(int y, int m, int d,
                      int *ly, int *lm, int *ld, int *isLeap) {
    // 1. 先算公历偏移天数
    int offset = daysFromBase(y, m, d);

    // 2. 逐年扣减农历年的天数，找到农历年
    int year = BASE_YEAR;
    while (offset >= getYearDays(year)) {
        offset -= getYearDays(year);
        year++;
    }
    *ly = year;

    // 3. 逐月扣减，找到农历月和是否闰月
    int leapMonth = getLeapMonth(year);
    int month = 1;
    *isLeap = 0;
    while (true) {
        int md;
        // 如果下一个月是闰月
        if (leapMonth == month && *isLeap == 0) {
            // 先扣闰月
            md = getLeapDays(year);
            *isLeap = 1;
        } else {
            // 正常月
            md = getMonthDays(year, month);
            // 如果上一轮是闰月，扣完后重置
            if (*isLeap == 1) *isLeap = 0;
        }

        if (offset < md) break;

        offset -= md;

        // 如果刚扣的是正常月，且它后面有闰月，就设置下轮扣闰
        if (*isLeap == 0 && month == leapMonth) {
            *isLeap = 1;
        } else {
            // 否则月份＋＋
            if (*isLeap == 1) *isLeap = 0;
            month++;
        }
    }

    *lm = month;
    *ld = offset + 1;
}



// 农历->公历
// 农历->公历核心（不依赖 time_t，支持1900–2100）
bool tryLunarToSolar(int ly, int lm, int ld, bool isLeapMonth,
                     int *ry, int *rm, int *rd) {
    if (ly < MIN_LUNAR_YEAR || ly > MAX_YEAR) return false;

    // 1. 计算偏移天数（从1900-01-31起算）
    int offset = 0;
    for (int y = BASE_YEAR; y < ly; y++)
        offset += getYearDays(y);

    int leapMonth = getLeapMonth(ly);
    for (int m = 1; m < lm; m++) {
        offset += getMonthDays(ly, m);
        if (m == leapMonth)
            offset += getLeapDays(ly);
    }
    if (isLeapMonth && lm == leapMonth)
        offset += getMonthDays(ly, lm);

    // 当月有效天数检查
    int thisMonthDays = (isLeapMonth && lm == leapMonth)
                      ? getLeapDays(ly)
                      : getMonthDays(ly, lm);
    if (ld < 1 || ld > thisMonthDays)
        return false;

    offset += ld - 1;

    // 2. 日数滚动转换到公历日期
    int y0 = 1900, m0 = 1, d0 = 31 + offset;
    while (true) {
        int dim = getGregorianMonthDays(y0, m0);
        if (d0 <= dim) break;
        d0 -= dim;
        m0++;
        if (m0 > 12) {
            m0 = 1;
            y0++;
        }
    }

    *ry = y0;
    *rm = m0;
    *rd = d0;
    return true;
}


bool lunarToSolarWithLeap(int ly, int lm, int ld, bool isLeap, int *ry, int *rm, int *rd) {
    if (ly < MIN_LUNAR_YEAR || ly > MAX_YEAR) return false;
    int offset = 0;

    // 累加过去年份天数
    for (int y = BASE_YEAR; y < ly; y++) {
        offset += getYearDays(y);
    }

    int leapMonth = getLeapMonth(ly);
    for (int m = 1; m < lm; m++) {
        offset += getMonthDays(ly, m);
        if (m == leapMonth) {
            offset += getLeapDays(ly);
        }
    }

    // 如果是闰月，再加上正常月的天数
    if (lm == leapMonth && isLeap) {
        offset += getMonthDays(ly, lm);
    }

    // 本月第 ld 天（offset 从 0 开始计）
    offset += ld - 1;

    // 基准日 1900-01-31
    struct tm base = {0};
    base.tm_year = 1900 - 1900;
    base.tm_mon  = 0;
    base.tm_mday = 31;
    time_t bt = mktime(&base);

    time_t tt = bt + (time_t)offset * 86400;
    struct tm *t = localtime(&tt);
    if (!t) {
        return false;
    }

    *ry = t->tm_year + 1900;
    *rm = t->tm_mon + 1;
    *rd = t->tm_mday;
    return true;
}




// —— 格式化并打印 “改良月历”  ——
void showCalendarEnhanced(int y, int m, int selDay) {
    // 1. 计算当月 1 号是星期几
    struct tm first = {0};
    first.tm_year = y - 1900;
    first.tm_mon  = m - 1;
    first.tm_mday = 1;
    mktime(&first);
    int start_wday = first.tm_wday;

    // 2. 当月天数
    int mdays[] = {31,28,31,30,31,30,31,31,30,31,30,31};
    bool leapG = (y%4==0 && y%100!=0) || (y%400==0);
    int days = mdays[m-1] + (m==2 && leapG);

    // 3. 打印表头
    wprintf(L"\n%4d年 %2d月\n", y, m);
    wprintf(L"日      一      二      三      四      五      六\n");

    // 4. 打印首行空格
    for (int i = 0; i < start_wday; i++) {
        wprintf(L"%8ls", L"");
    }

    // 5. 逐天打印
    for (int d = 1; d <= days; d++) {
        int w = (start_wday + d - 1) % 7;

        // 5.1 计算农历
        int ly, lm, ld, isLeapMonth;
        solarToLunarDate(y, m, d, &ly, &lm, &ld, &isLeapMonth);

        // 5.2 节气标记
        wchar_t termMark[16] = L"";
        for (int idx = 0; idx < 24; idx++) {
            if ((idx/2 + 1) == m && getSolarTermDay(y, idx) == d) {
                swprintf(termMark, 16, L"*%ls", solarTerms[idx]);
                break;
            }
        }

        // 5.3 颜色高亮
        const wchar_t *start = L"", *end = L"\x1b[0m";
        if (termMark[0] != L'\0') {
            start = L"\x1b[31m";
        } else if (w == 0 || w == 6) {
            start = L"\x1b[34m";
        }

        // 5.4 构造并输出单元格
        wchar_t buf[32];
        swprintf(buf, 32,
                 L"%2d(%ls%d月%02d%ls)",
                 d,
                 isLeapMonth ? L"闰" : L"",
                 lm,
                 ld,
                 termMark);
        wprintf(L"%s%8ls%s", start, buf, end);

        if (w == 6) wprintf(L"\n");
    }
    wprintf(L"\n");
    
}





// 公历查询模块
void querySolarToLunar() {
    int y, m, d;
    wprintf(L"输入公历日期 (YYYY MM DD): ");
    if (wscanf(L"%d %d %d", &y, &m, &d) != 3) return;

    int ly, lm, ld, isLeap;
    solarToLunarDate(y, m, d, &ly, &lm, &ld, &isLeap);

    // 1. 打印当月改良月历
    showCalendarEnhanced(y, m,d);

    // 2. 天干地支
    const wchar_t *heavenlyStems[] = {L"甲",L"乙",L"丙",L"丁",L"戊",L"己",L"庚",L"辛",L"壬",L"癸"};
    const wchar_t *earthlyBranches[] = {L"子",L"丑",L"寅",L"卯",L"辰",L"巳",L"午",L"未",L"申",L"酉",L"戌",L"亥"};
    int tg = (ly - 4) % 10;
    int dz = (ly - 4) % 12;
    wprintf(L"农历: %04d年 %ls%ls年 %d月 %02d日\n", ly,
            heavenlyStems[tg], earthlyBranches[dz], lm, ld);

    // 3. 节气判断与提示
    struct tm today = {0};
    today.tm_year = y - 1900;
    today.tm_mon  = m - 1;
    today.tm_mday = d;
    time_t t0 = mktime(&today);
    bool isTerm = false;
    for (int i = 0; i < 24; i++) {
        int termMonth = i / 2 + 1;
        int termDay   = getSolarTermDay(y, i);
        if (termMonth == m && termDay == d) {
            wprintf(L"今日节气：%ls\n", solarTerms[i]);
            isTerm = true;
            break;
        }
    }
    if (!isTerm) {
        int diffDays = 0;
        for (int i = 0; i < 24; i++) {
            int termMonth = i / 2 + 1;
            int termDay   = getSolarTermDay(y, i);
            struct tm t1 = {0};
            t1.tm_year = y - 1900;
            t1.tm_mon  = termMonth - 1;
            t1.tm_mday = termDay;
            time_t tTerm = mktime(&t1);
            double df    = difftime(tTerm, t0) / 86400.0;
            if (df > 0) { diffDays = (int)df; break; }
        }
        wprintf(L"距离下一节气还有 %d 天\n", diffDays);
    }

    // 4. 当月节气列表
    wprintf(L"当月节气：");
    for (int i = 0; i < 24; i++) {
        int termMonth = i / 2 + 1;
        if (termMonth == m) {
            int termDay = getSolarTermDay(y, i);
            wprintf(L"  %ls: %d日", solarTerms[i], termDay);
        }
    }
}

//农历查询模块
void queryLunarToSolar() {
    int ly, lm, ld;
    wprintf(L"请输入农历日期 (YYYY MM DD)：");
    fflush(stdout);
    if (wscanf(L"%d %d %d", &ly, &lm, &ld) != 3) {
        wprintf(L"输入格式错误，应为 年 月 日 三个整数！\n");
        return;
    }

    // 年份范围
    if (ly < MIN_LUNAR_YEAR || ly > MAX_YEAR) {
        wprintf(L"年份超出支持范围 (%d~%d)\n", MIN_LUNAR_YEAR, MAX_YEAR);
        return;
    }

    // 判断是否属于闰月
    int leapMonth = getLeapMonth(ly);
    bool isLeap = false;
    int monthDays = getMonthDays(ly, lm);

    if (leapMonth == lm) {
        int leapDays = getLeapDays(ly);
        if      (ld > monthDays && ld <= monthDays + leapDays) {
            // 闰月
            isLeap = true;
            ld   -= monthDays;
            monthDays = leapDays;
        }
        else if (ld < 1 || ld > monthDays) {
            wprintf(L"该月最多 %d 天，输入日期非法\n", monthDays);
            return;
        }
    }
    else {
        if (ld < 1 || ld > monthDays) {
            wprintf(L"该月最多 %d 天，输入日期非法\n", monthDays);
            return;
        }
    }

    // 调用转换
    int ry, rm, rd;
    if (tryLunarToSolar(ly, lm, ld, isLeap, &ry, &rm, &rd)) {
        wprintf(L"对应公历: %04d-%02d-%02d\n", ry, rm, rd);
    } else {
        wprintf(L"转换失败，超出支持范围或日期非法\n");
    }
}


//获取当前时间
void GetCurTime(wchar_t *buf, int len) {
    if (!buf || len < 20) return; // 至少需要20字符空间
    time_t t = time(NULL);
    struct tm *now = localtime(&t);
    if (!now) { buf[0] = L'\0'; return; }
    wcsftime(buf, len, L"当前时间：%Y-%m-%d %H:%M:%S", now);
}


// 天干地支计算
void getGanZhi(int year, wchar_t *buf) {
    const wchar_t *tiangan[] = {L"甲", L"乙", L"丙", L"丁", L"戊", L"己", L"庚", L"辛", L"壬", L"癸"};
    const wchar_t *dizhi[] = {L"子", L"丑", L"寅", L"卯", L"辰", L"巳", L"午", L"未", L"申", L"酉", L"戌", L"亥"};
    int tg = (year - 4) % 10;
    int dz = (year - 4) % 12;
    swprintf(buf, 16, L"%ls%ls年", tiangan[tg], dizhi[dz]);
}


//显示菜单
void showMenu() {
#ifdef _WIN32
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
#endif
    wprintf(L"\n========== 超级万年历 ==========");

    wchar_t timeStr[64];
    GetCurTime(timeStr, 64);
#ifdef _WIN32
    SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
#endif
    wprintf(L"\n%ls\n", timeStr);
#ifdef _WIN32
    SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
#endif

    wprintf(L"\n1. 公历->农历\n2. 农历->公历\n3. 显示月历\n4. 查询某天距今天的天数\n5. 距今天n天的日期\n6. 两日期之间的间隔\n7. 显示二十四节气\n8. 显示节日\n0. 退出\n请选择操作：");
}



void daysFromToday() {
    int y, m, d;
    // 1. 读入目标日期
    wprintf(L"请输入目标日期（YYYY MM DD）：");
    wscanf(L"%d %d %d", &y, &m, &d);

    // 2. 获取今天日期的 tm 结构
    time_t now_time = time(NULL);
    struct tm today_tm = *localtime(&now_time);
    // 把时分秒归零，只保留日期
    today_tm.tm_hour = 0;
    today_tm.tm_min  = 0;
    today_tm.tm_sec  = 0;
    // 标准化
    mktime(&today_tm);

    // 3. 构造目标日期的 tm 结构，也归零时分秒
    struct tm tgt_tm = {0};
    tgt_tm.tm_year = y - 1900;
    tgt_tm.tm_mon  = m - 1;
    tgt_tm.tm_mday = d;
    tgt_tm.tm_hour = 0;
    tgt_tm.tm_min  = 0;
    tgt_tm.tm_sec  = 0;
    // 标准化
    mktime(&tgt_tm);

    // 4. 计算日期差（以天为单位）
    time_t t_today = mktime(&today_tm);
    time_t t_tgt   = mktime(&tgt_tm);
    double diff_seconds = difftime(t_tgt, t_today);
    int diff_days = (int)fabs(diff_seconds / 86400.0);

    // 5. 按早/晚分别输出
    if (t_tgt < t_today) {
        // 输入日期早于今天
        wprintf(L"%d %d %d 比今天（%d-%02d-%02d） 早 【%d】 天\n",
            y, m, d,
            today_tm.tm_year + 1900,
            today_tm.tm_mon + 1,
            today_tm.tm_mday,
            diff_days
        );
    }
    else if (t_tgt > t_today) {
        // 输入日期晚于今天
        wprintf(L"%d %d %d 比今天（%d-%02d-%02d） 晚 【%d】 天\n",
            y, m, d,
            today_tm.tm_year + 1900,
            today_tm.tm_mon + 1,
            today_tm.tm_mday,
            diff_days
        );
    }
    else {
        // 输入日期就是今天
        wprintf(L"%d %d %d 就是今天！（%d-%02d-%02d）\n",
            y, m, d,
            today_tm.tm_year + 1900,
            today_tm.tm_mon + 1,
            today_tm.tm_mday
        );
    }
}


void dateFromToday() {
    int n;
    // 1. 读取用户输入的天数
    wprintf(L"请输入天数（正整数）：");
    wscanf(L"%d", &n);

    // 2. 获取今天的日期（归零时分秒以按天计算）
    time_t now_time = time(NULL);
    struct tm today = *localtime(&now_time);
    today.tm_hour = today.tm_min = today.tm_sec = 0;
    mktime(&today);  // 标准化

    // 3. 计算前后两个日期的 time_t
    time_t t_today  = mktime(&today);
    time_t t_before = t_today - (time_t)n * 86400;
    time_t t_after  = t_today + (time_t)n * 86400;

    // 4. 把 localtime 的结果拷贝到各自的 struct tm
    struct tm res_before = *localtime(&t_before);
    struct tm res_after  = *localtime(&t_after);

    // 5. 输出
    wprintf(
        L"比今天（%04d-%02d-%02d）早%d天的日期：%04d-%02d-%02d\n"
        L"比今天（%04d-%02d-%02d）晚%d天的日期：%04d-%02d-%02d\n",
        // 今天
        today.tm_year + 1900, today.tm_mon + 1, today.tm_mday, n,
        // 之前的日期
        res_before.tm_year + 1900, res_before.tm_mon + 1, res_before.tm_mday,
        // 今天（重复一次）
        today.tm_year + 1900, today.tm_mon + 1, today.tm_mday, n,
        // 之后的日期
        res_after.tm_year + 1900,  res_after.tm_mon + 1,  res_after.tm_mday
    );
}


// 判断是否为闰年
bool isLeap(int year) {
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

// 验证日期合法性
bool isValidDate(int y, int m, int d) {
    if (y < 1900 || m < 1 || m > 12 || d < 1) return false;
    int mdays[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
    if (m == 2 && isLeap(y)) {
        if (d > 29) return false;
    } else {
        if (d > mdays[m]) return false;
    }
    return true;
}

void daysBetween() {
    int y1, m1, d1, y2, m2, d2;

    wprintf(L"请输入第一个日期（YYYY MM DD）：");
    wscanf(L"%d %d %d", &y1, &m1, &d1);
    wprintf(L"请输入第二个日期（YYYY MM DD）：");
    wscanf(L"%d %d %d", &y2, &m2, &d2);

    // 1. 检查日期合法性
    if (!isValidDate(y1, m1, d1) || !isValidDate(y2, m2, d2)) {
        wprintf(L"输入日期有误，请检查后重新运行程序。\n");
        return;
    }

    // 2. 构造 tm 结构并归零时分秒
    struct tm t1 = {0}, t2 = {0};
    t1.tm_year = y1 - 1900;  t1.tm_mon = m1 - 1;  t1.tm_mday = d1;
    t2.tm_year = y2 - 1900;  t2.tm_mon = m2 - 1;  t2.tm_mday = d2;
    // 归零
    t1.tm_hour = t1.tm_min = t1.tm_sec = 0;
    t2.tm_hour = t2.tm_min = t2.tm_sec = 0;
    // 标准化（可选，但推荐）
    mktime(&t1);
    mktime(&t2);

    // 3. 计算天数差
    time_t time1 = mktime(&t1);
    time_t time2 = mktime(&t2);
    double secs = difftime(time1, time2);
    int diff_days = abs((int)(secs / 86400.0));

    // 4. 输出结果
    wprintf(
        L"日期 %04d-%02d-%02d 与 %04d-%02d-%02d 相差 【%d】 天\n",
        y1, m1, d1,
        y2, m2, d2,
        diff_days
    );
}


void showSolarTerms() {
    int year;
    wprintf(L"请输入年份（1900~2100）：");
    wscanf(L"%d", &year);
    if (year < 1900 || year > 2100) {
        wprintf(L"超出支持范围！\n");
        return;
    }
    wprintf(L"%d 年二十四节气：\n", year);
    for (int i = 0; i < 24; i++) {
        int month = i / 2 + 1;
        int day = (int)(solarTermInfo[i] + (year - 1900) * 0.2422 - (int)((year - 1900) / 4));
        wprintf(L"%ls：%d月%d日\n", solarTerms[i], month, day);
    }
}

void showFestivals() {
    int choice;
    wprintf(L"请选择：1. 公历节日  2. 农历节日\n");
    wscanf(L"%d", &choice);
    if (choice == 1) {
        int month;
        wprintf(L"请输入要查询的月份（1~12）：");
        wscanf(L"%d", &month);
        if (month < 1 || month > 12) {
            wprintf(L"月份输入错误！\n");
            return;
        }
        wprintf(L"\n公历 %d 月节日：\n", month);
        for (int i = 0; i < sizeof(solarFestivals)/sizeof(solarFestivals[0]); i++) {
            int m;
            swscanf(solarFestivals[i][0], L"%d", &m);
            if (m == month) {
                wprintf(L"%ls: %ls\n", solarFestivals[i][0], solarFestivals[i][1]);
            }
        }
    } else if (choice == 2) {
        wprintf(L"\n农历节日列表：\n");
        for (int i = 0; i < sizeof(lunarFestivals)/sizeof(lunarFestivals[0]); i++) {
            wprintf(L"%ls\n", lunarFestivals[i]);
        }
    } else {
        wprintf(L"无效选择！\n");
    }
}


int main() {
    setlocale(LC_ALL, ""); // 支持中文输入输出
    initLocale();
    int choice;
    do {
        showMenu();
        if (wscanf(L"%d", &choice) != 1) { fflush(stdin); choice = -1; continue; }
        switch (choice) {
            case 1: querySolarToLunar(); break;
            case 2: queryLunarToSolar(); break;
            case 3: {
                int y,m,d; wprintf(L"输入年月(YYYY MM):"); wscanf(L"%d%d",&y,&m);
                showCalendarEnhanced(y,m,d);
            } break;
            case 4: daysFromToday(); break;
            case 5: dateFromToday(); break;
            case 6: daysBetween(); break;
            case 7: showSolarTerms(); break;
            case 8: showFestivals(); break;
            case 0: wprintf(L"退出程序。\n"); break;
            default: wprintf(L"无效选择\n"); break;
        }
        if (choice != 0) { wprintf(L"\n按回车返回菜单...\n"); fflush(stdin); getchar(); getchar(); }
    } while (choice != 0);
    return 0;
}
